/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦，本文采用木兰宽松许可证第2版]
 * 
 * https://zhiqim.org/project/zhiqim_kit/zhiqim_git.htm
 *
 * ZhiqimGit is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.git.objer.model;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

import org.zhiqim.git.GitConstants;
import org.zhiqim.git.objer.objectid.ObjectId;

import org.zhiqim.kernel.util.mutables.MInt;
import org.zhiqim.kernel.util.Asserts;
import org.zhiqim.kernel.util.Bytes;

/**
 * 标签模型对象
 * 
 * 格式如下：
 * object 6f07a489f21c77047449ec4cff783f311d47c74b
 * type commit
 * tag V1.0.1
 * tagger zzg <zzg@zhiqim.org> 1490842716 +0800
 * 
 * 发布V1.0.1版本
 *
 * @version v1.0.0 @author zouzhigang 2017-4-15 新建与整理
 */
public class Tag implements GitConstants
{
    private ObjectId object;            //对象编号
    private String type;                //对象类型
    private String tag;                 //标签名称
    private PersonIdent tagger;         //标签作者
    private String message;             //标签信息
    
    /******************************************************************************/
    //标签五个参数设置
    /******************************************************************************/
    
    public Tag setObject(ObjectId object)
    {
        this.object = object;
        return this;
    }
    
    public Tag setType(String type)
    {
        this.type = type;
        return this;
    }

    public Tag setTag(String tag)
    {
        this.tag = tag;
        return this;
    }

    public Tag setTagger(PersonIdent tagger)
    {
        this.tagger = tagger;
        return this;
    }
    
    public Tag setMessage(final String message)
    {
        this.message = message;
        return this;
    }
    
    /******************************************************************************/
    //标签五个参数获取
    /******************************************************************************/
    
    public ObjectId getObject()
    {
        return object;
    }
    
    public String getType()
    {
        return type;
    }
    
    public String getTag()
    {
        return tag;
    }
    
    public PersonIdent getTagger()
    {
        return tagger;
    }

    public String getMessage()
    {
        return message;
    }
    
    /******************************************************************************/
    //解析&生成
    /******************************************************************************/
    
    /** 解析 */
    public Tag parse(byte[] raw)
    {
        Asserts.assertNotNull(raw, "解析标签时，字节数组为null");
        
        MInt off = new MInt();
        
        //1.object
        String line = Bytes.BU.getString(raw, off, _LF_);
        Asserts.assertStartsWith(line, "object ", "解析标签时，格式错误，没有object标识");
        object = ObjectId.parse(line.substring(P_OBJECT.length));
        
        //2.type
        line = Bytes.BU.getString(raw, off, _LF_);
        Asserts.assertStartsWith(line, "type ", "解析标签时，格式错误，没有type标识");
        type = line.substring(P_TYPE.length);
        
        //3.tag
        line = Bytes.BU.getString(raw, off, _LF_);
        Asserts.assertStartsWith(line, "tag ", "解析标签时，格式错误，没有tag标识");
        tag = line.substring(P_TAG.length);
        
        //4.tagger
        line = Bytes.BU.getString(raw, off, _LF_);
        Asserts.assertStartsWith(line, "tagger ", "解析标签时，格式错误，没有tagger标识");
        tagger = new PersonIdent(line.substring(P_TAGGER.length));
        
        //5.message
        off.skip(1);//跳过空行
        message = Bytes.BU.getString(raw, off);
        
        return this;
    }
    
    /** 生成 */
    public byte[] build() throws IOException
    {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        OutputStreamWriter writer = new OutputStreamWriter(out, _UTF_8_);

        writer.write("object ");
        object.copyTo(writer);
        writer.write('\n');

        writer.write("type ");
        writer.write(type);
        writer.write("\n");

        writer.write("tag ");
        writer.write(tag);
        writer.write("\n");

        writer.write("tagger ");
        writer.write(tagger.toExternalString());
        writer.write('\n');

        writer.write('\n');
        writer.write(message);
        writer.close();

        return out.toByteArray();
    }
    
    /******************************************************************************/
    //toString
    /******************************************************************************/
    
    public String toString()
    {
        return "标签[" + tag + type + object + " " + tagger + "]";
    }
}
